<?php

namespace App\Kuafu\User\Model;

use Alipay\EasySDK\Kernel\Util\PageUtil;
use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Model\Traits\KfSoftDeletes;
use App\Kuafu\Base\Model\Traits\KfUid;
use App\Kuafu\Nsq\Enum\NsqCodeEnum;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopStaffRecordModel;
use App\Kuafu\User\Enum\CodeEnum as UserEnum;
use App\Kuafu\User\Enum\RoleCodeEnum;
use App\Kuafu\User\Enum\UserCacheEnum;
use App\Kuafu\User\Service\RoleService;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Cache;
use App\Kuafu\Shop\Enum\CodeEnum as ShopEnum;
use Kuafu\File\FileUtil;


class UserRoleMapping extends BaseModel
{
    use KfSoftDeletes, KfUid;

    protected $connection = 'mysql';
    protected $table      = 'user_role_mappings';
    protected $primaryKey = 'id';
    protected $fillable   = [
        'userId',
        'roleId',
        'brandId',
        'shopId',
        'createdByUid',
        'updatedByUid',
    ];

    /*
     * 平台类型
     */
    protected static $platform = 0;

    /**
     * 是否在店
     */
    const IN_SHOP_ON      = 0;
    const IN_SHOP_OFF     = 1;
    const IN_SHOP_MAPPING = [
        self::IN_SHOP_ON  => '是',
        self::IN_SHOP_OFF => '否',
    ];


    public function roleRel()
    {
        return $this->belongsTo(Role::class, 'roleId')
                    ->where('status', 0)
                    ->when(self::$platform >= 0, function ($query) {
                        $query->where('platform', self::$platform);
                    });
    }

    public function roleRelNoPlatform()
    {
        return $this->belongsTo(Role::class, 'roleId')->where('status', 0);
    }

    public function roleManyRel()
    {
        return $this->hasOne(Role::class, 'id', 'roleId');
    }

    public function userRel()
    {
        return $this->belongsTo(User::class, 'userId');
    }

    public function roleIdsManyRel()
    {
        return $this->hasMany(Role::class, 'id', 'roleId');
    }

    /**
     * 查
     * @param int $userId
     * @param int $brandId
     * @param int $shopId
     * @return Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function getDataFirst(int $userId, int $brandId, int $shopId)
    {
        return UserRoleMapping::query()
                              ->with('roleRel')
                              ->where('userId', $userId)
                              ->where('brandId', $brandId)
                              ->where('shopId', $shopId)
                              ->select(['roleId', 'id'])
                              ->first();
    }

    /**
     * 获取用户在 WEB 的角色列表
     * 夸父订货系统 依赖此方法
     *
     * @param int $userId
     * @param int $brandId
     */
    public static function getUserRoleList(int $userId, int $brandId, int $shopId, int $type)
    {
        // TODO 缓存
        return self::query()
                   ->where('userId', $userId)
                   ->where('brandId', $brandId)
                   ->where('shopId', $shopId)
                   ->where('type', $type)
                   ->get();
    }

    /**
     * 通过品牌 Id 返回角色 Id
     *
     * @param int $userId
     * @param int $brandId
     * @return int
     */
    public static function getUserRoleIdByBrandId(int $userId, int $brandId, int $platform): int
    {
        self::$platform = $platform;

        $data = self::query()
                    ->where('userId', $userId)
                    ->where('brandId', $brandId)
                    ->where('shopId', 0)
                    ->with('roleRel')
                    ->first();

        if (empty($data->roleRel)) {
            return 0;
        } else {
            return $data->roleRel->id ?? 0;
        }
    }

    /**
     * 通过店铺 Id 返回角色 Id
     *
     * @param int $userId
     * @param int $shopId
     * @return int
     */
    public static function getUserRoleByShopId(int $userId, int $shopId, int $platform): int
    {
        self::$platform = $platform;

        $data = self::query()
                    ->where('userId', $userId)
                    ->where('shopId', $shopId)
                    ->with('roleRel')
                    ->first();

        if (empty($data) || empty($data->roleRel)) {
            return 0;
        } else {
            return $data->roleRel->id ?? 0;
        }
    }

    /**
     * 根据 userId, 平台类型 查询用户所拥有的店铺列表
     *
     *
     * @param int $userId
     * @param int $platform
     * @return array
     */
    public static function getUserShopListByUserId(int $userId, int $platform): array
    {
        self::$platform = $platform;

        $data = self::query()
                    ->where('userId', $userId)
                    ->where('shopId', '<>', 0)
                    ->with('roleRel')
                    ->get()
                    ->reject(
                        function ($value) {
                            if (empty($value->roleRel)) {
                                return true;
                            }
                        })
                    ->values()
                    ->pluck('shopId')
                    ->toArray();

        return $data;
    }

    /**
     * 根据 userId, 平台类型 查询用户所拥有的店铺列表
     *
     *
     * @param int $userId
     * @param int $platform
     * @return array
     */
    public static function getShopListByUserId(int $userId, int $platform): array
    {
        $type = RoleService::switchPlatformToType($platform);
        // 获取用户所有店铺信息
        $data = self::query()
                    ->where('userId', $userId)
                    ->where('type', $type)
                    ->with('roleRelNoPlatform')
                    ->get()
                    ->reject(
                        function ($value) {
                            if (empty($value->roleRelNoPlatform)) {
                                return true;
                            }
                        })
                    ->values()
                    ->pluck('shopId')
                    ->toArray();

        return $data;
    }

    /**
     * 根据 userId, 平台类型 查询用户所拥有的店铺列表 - 带缓存
     * @param int $userId
     * @param int $platform
     * @return array
     */
    public static function getShopListByUserIdCache(int $userId, int $platform): array
    {
        return Cache::remember(UserCacheEnum::getUserShopIds($userId, $platform), 60,
            function () use ($userId, $platform) {
                return self::getShopListByUserId($userId, $platform);
            });
    }

    /**
     * 根据 shopId,type 获取用户,角色列表
     *
     * @param $shopId
     * @param $platform
     * @return array
     */
    public static function getUserIdsByShopIds($shopId, $type)
    {
        // 获取店铺内绑定用户信息
        $list = self::query()
                    ->whereIn('type', $type)
                    ->where('shopId', $shopId)
                    ->with(['userRel'])
                    ->withoutGlobalScope('isDel')
                    ->get();

        // // 该门店下拥有身份证的用户列表
        // $haveIdCardUserIds = UserIdCardDetailModel::query()
        //     ->whereIn('userId', $list->pluck('userId')->toArray())
        //     ->pluck('userId')
        //     ->toArray();

        // 获得门店员工状态
        $shopStaffPositionStatus = ShopStaffRecordModel::query()
            ->where('shopId', $shopId)
            ->get()
            ->keyBy('userId')
            ->toArray();

        // 获取权限列表
        $roleList = $list->pluck('roleId');
        $roleList = Role::getRoleListByIds($roleList)->keyBy('id')->toArray();

        return $list->map(function (UserRoleMapping $userRoleMapping) use ($roleList, $shopStaffPositionStatus) {
            if ($userRoleMapping->userRel == null || !isset($shopStaffPositionStatus[$userRoleMapping->userId])) {
                return null;
            }

            $shopStaffModel = $shopStaffPositionStatus[$userRoleMapping->userId];
            $data           = $userRoleMapping->toArray();

            // 用户头像
            if (strlen($userRoleMapping->userRel->avatar)) {
                $data['user_rel']['avatar'] = FileUtil::domain() . '/' . $userRoleMapping->userRel->avatar;
            }

            // 用户门店在职状态 不与RMS关联
            $data['user_rel']['status'] = $shopStaffModel['positionStatus'] ?? ShopStaffRecordModel::POSITION_STATUS_OFF;

            // 获取在证件总状态
            $cardStatus       = '';
            $appletCardStatus = '';  // 小程序状态处理
            if ($userRoleMapping->isDeleted == 0 && $shopStaffModel['inShop'] == ShopStaffRecordModel::IN_SHOP_ON) {
                if ($shopStaffModel['idCardStatus'] == ShopStaffRecordModel::ID_CARD_STATUS_LACK || $shopStaffModel['healthCardStatus'] == ShopStaffRecordModel::HEALTH_CARD_STATUS_LACK) {
                    $cardStatus       = '证件缺失';
                    $appletCardStatus = '证件缺失/过期';
                } elseif ($shopStaffModel['healthCardStatus'] == ShopStaffRecordModel::HEALTH_CARD_STATUS_EXPIRED) {
                    $cardStatus       = '证件过期';
                    $appletCardStatus = '证件缺失/过期';
                } elseif ($shopStaffModel['auditStatus'] == ShopStaffRecordModel::AUDIT_STATUS_REJECT) {
                    $cardStatus       = '未通过审查';
                    $appletCardStatus = '已驳回';
                } elseif ($shopStaffModel['healthCardStatus'] == ShopStaffRecordModel::HEALTH_CARD_STATUS_ABOUT_TO_EXPIRE) {
                    $cardStatus       = '即将到期';
                    $appletCardStatus = '即将到期';
                } elseif ($shopStaffModel['auditStatus'] == ShopStaffRecordModel::AUDIT_STATUS_PASS) {
                    $appletCardStatus = '已通过';
                } elseif ($shopStaffModel['auditStatus'] == ShopStaffRecordModel::AUDIT_STATUS_WAIT_AUDIT) {
                    $appletCardStatus = '待审核';
                }
            }

            $data['entryTime']        = $shopStaffModel['entryTime'] ? Carbon::createFromTimestamp($shopStaffModel['entryTime'])->toDateString() : '';;
            $data['cardStatus']       = $cardStatus;
            $data['inShop']           = $shopStaffModel['inShop'];
            $data['healthCardStatus'] = $shopStaffModel['healthCardStatusText'];
            $data['idCardStatus']     = $shopStaffModel['idCardStatusText'];
            $data['appletCardStatus'] = $appletCardStatus;

            if (key_exists($userRoleMapping->roleId, $roleList)) {
                $data['roleInfo'] = $roleList[$userRoleMapping->roleId];
            } else {
                return null;
            }

            return $data;
        })->filter()->values()->toArray();
    }

    /**
     * 获取拥有运营中心权限的所有用户
     * @return array
     */
    public static function getWebUserIds(): array
    {
        return self::query()
                   ->where('type', RoleCodeEnum::ROLE_WEB_TYPE)
                   ->pluck('userId')
                   ->unique()
                   ->values()
                   ->toArray();
    }

    /**
     * 获取拥有运营中心权限的所有用户
     * @return array
     */
    public static function getSiteTaskHandlerList(): array
    {
        // 对应kf_role的ID
        if (config('app.env') == 'prod' || config('app.env') == 'pre') {
            $role = 87;
        } else {
            $role = 52;
        }
        return self::query()
                   ->where('roleId', $role)
                   ->pluck('userId')
                   ->unique()
                   ->values()
                   ->toArray();
    }

    /**
     * 获取roleId的数量
     *
     * @param int $roleId
     * @return int
     */
    public static function countRoleId(int $roleId): int
    {
        return self::query()->where('roleId', $roleId)->count();
    }

    /**
     * 批量添加 关系数据
     */
    public static function batchAddUserRoleMapping($data)
    {
        $result = self::query()->insert($data);

        return $result;
    }

    public static function delData(int $userId)
    {
        return UserRoleMapping::query()->where('userId', $userId)->delete();
    }

    /**
     * 根据 角色ids 获取角色信息
     *
     * @param array $userIds
     * @param int $brandId
     * @return array
     */
    public static function getRoleListByUserIds(array $userIds = [], int $brandId = 0)
    {
        $data = self::query()
                    ->with('roleManyRel')
                    ->whereIn('userId', $userIds)
                    ->where('brandId', $brandId)
                    ->get()
                    ->each(function ($value) {
                        $value->roleName = $value->roleManyRel->name ?? "没职位";
                    })->toArray();
        return $data;
    }

    public function rolesRel()
    {
        return $this->hasOne(
            Role::class,
            'id',
            'roleId'
        );
    }


    public static function getStaffRoles($userId, $shopId, $brandId, $isDeleted = null)
    {
        return self::query()
                   ->where('userId', '=', $userId)
                   ->where('shopId', '=', $shopId)
                   ->where('brandId', '=', $brandId)
                   ->withoutGlobalScope('isDel')
                   ->when($isDeleted != null, function ($query) use ($isDeleted) {
                       $query->where('isDeleted', '=', $isDeleted);
                   })
                   ->select(['roleId', 'type', 'isDeleted'])
                   ->get();
    }

    //获取员工可用权限
    public static function getStaffRole($userId, $shopId, $brandId, $isDeleted = UserEnum::APP_USER_NORMAL_ROLE)
    {
        $lists = UserRoleMapping::query()
                                ->where('userId', '=', $userId)
                                ->where('shopId', '=', $shopId)
                                ->where('brandId', '=', $brandId)
                                ->when($isDeleted != UserEnum::APP_USER_NORMAL_ROLE, function ($query) {
                                    $query->withoutGlobalScope('isDel')
                                          ->where('isDeleted', '=', UserEnum::APP_USER_DELETED_ROLE);
                                })
                                ->get('roleId')
                                ->toArray();
        $roles = [];
        foreach ($lists as $item) {
            $roles[] = $item['roleId'];
        }
        return $roles;
    }

    /**
     * @param $userId
     * @param $shopId
     * @param $roleId
     * @param $brand
     * @param $type
     * @return int
     */
    public static function rmUserRole($userId, $shopId, $roleId, $brand, $type): int
    {
        $res = self::query()
                   ->where("shopId", $shopId)
                   ->where("userId", $userId)
                   ->where("roleId", $roleId)
                   ->where("brandId", $brand)
                   ->where("type", $type)
                   ->update(["isDeleted" => 1]);

        // 门店员工删除事件通知
        (new \Kuafu\Nsq\NsqPublisher(config('nsq.default.address')))
            ->pub(NsqCodeEnum::SHOP_STAFF_EVENT, [
                'userId'  => $userId,
                'shopId'  => $shopId,
                'type'    => $type,
                'isExist' => 1,// 删除
            ]);
        return $res;
    }

    public static function addUserRoleMap($userId, $shopId, $roleId, $brand, $type, int $induction = 0, int $inShop = 0): bool
    {
        $models          = new UserRoleMapping();
        $models->userId  = $userId;
        $models->shopId  = $shopId;
        $models->roleId  = $roleId;
        $models->brandId = $brand;
        $models->inShop  = $inShop;
        $models->type    = $type;

        if ($induction > 0) {
            $models->entryTime  = $induction;
        }

        $res             = $models->save();

        // 门店员工创建事件通知
        (new \Kuafu\Nsq\NsqPublisher(config('nsq.default.address')))
            ->pub(NsqCodeEnum::SHOP_STAFF_EVENT, [
                'userId'  => $userId,
                'shopId'  => $shopId,
                'roleId'  => $roleId,
                'type'    => $type,
                'isExist' => 0,// 加入
            ]);
        return $res;
    }

    public static function setIsDelStaff($userId, $shopId, $delUserRole, $brand, $updated)
    {
        $res = UserRoleMapping::query()
                              ->where('userId', $userId)
                              ->where('shopId', $shopId)
                              ->where('brandId', $brand)
                              ->whereIn('roleId', $delUserRole)
                              ->when($updated == 1, function ($query){
                                  $query->update([
                                      'isDeleted' => UserEnum::APP_USER_DELETED_ROLE
                                  ]);
                              })
                              ->when($updated == 0, function ($query){
                                  $query->withoutGlobalScope('isDel')->update([
                                      'isDeleted' => UserEnum::APP_USER_NORMAL_ROLE
                                  ]);
                              });

        // 门店员工更新/删除事件通知
        (new \Kuafu\Nsq\NsqPublisher(config('nsq.default.address')))
            ->pub(NsqCodeEnum::SHOP_STAFF_EVENT, [
                'userId'  => $userId,
                'shopId'  => $shopId,
                'isExist' => $updated,
            ]);
        return $res;
    }

    //用户设备关联
    public function userRegistrationMappingRel()
    {
        return $this->hasOne(UserRegistrationMappings::class, 'userId', 'userId');
    }

    public function ShopRel()
    {
        return $this->hasOne(Shop::class, 'id', 'shopId');
    }

    /**
     * 检查用户是否属于某个角色
     * @param int $brandId
     * @param int $shopId
     * @param int $userId
     * @param int $roleId
     * @return bool
     */
    public static function checkUserRole(int $brandId, int $shopId, int $userId, int $roleId): bool
    {
        return (bool)self::query()
                         ->where('brandId', $brandId)
                         ->where('shopId', $shopId)
                         ->where('userId', $userId)
                         ->where('roleId', $roleId)
                         ->count();
    }
}
